package com.ying.tests.BBBbook.java8.Chapter3;


import cn.hutool.core.lang.Filter;
import com.ying.tests.BBBbook.java8.Chapter1.Apple;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.*;

/**
 * 第三章：Lambda表达式
 */
public class Chapter3 {

    private static final Logger logger = LoggerFactory.getLogger(Chapter3.class);

    public static void main(String[] args) {
//        test1();
//        test2();
//        test3();
//        test4();
//        test5();
//        test6();
//        test7();
        test8();
    }

    /**
     * compareTo比较需要都转成包装类
     */
    private static void test1() {
        Comparator<Apple> appleComparator = new Comparator<Apple>() {
            @Override
            public int compare(Apple a1, Apple a2) {
                return Integer.valueOf(a1.getWeight()).compareTo(a2.getWeight());
            }
        };
        Comparator<Apple> comparator1 = (Apple a1, Apple a2) -> Integer.valueOf(a1.getWeight()).compareTo(a2.getWeight());
        Comparator<Apple> comparator2 = (Apple a1, Apple a2) -> Integer.compare(a1.getWeight(), a2.getWeight());
        Filter<List<String>> listFilter = (List<String> list) -> list.isEmpty();
    }

    /**
     * 函数式接口中可以传递lambda表达式
     */
    private static void test2() {
        Runnable r1 = () -> System.out.println("Hello world 1");
        Runnable r2 = new Runnable() {
            @Override
            public void run() {
                System.out.println("Hello world 2");
            }
        };
        process(r1);
        process(r2);
        process(() -> System.out.println("Hello world 3"));
    }
    public static void process(Runnable r) {
        r.run();
    }

    /**
     * 函数式接口的使用——Predicate
     */
    private static void test3() {
        List<String> strings = Arrays.asList("aaa", "", "bbb", "ccc");
        List<String> filter = filter(strings, nonEmptyStringPredicate);
        System.out.println(filter);
    }
    @FunctionalInterface
    public interface Predicate<T> {
        boolean test(T t);
    }
    public static <T> List<T> filter(List<T> list, Predicate<T> p) {
        List<T> result = new ArrayList<>();
        list.stream().forEach(l -> {
            if (p.test(l)) {
                result.add(l);
            }
        });
        return result;
    }
    static Predicate<String> nonEmptyStringPredicate = (String s) -> !s.isEmpty();

    /**
     * 函数式接口的使用——Consumer
     */
    private static void test4() {
        List<Integer> num = Arrays.asList(1, 2, 3, 4, 5);
        forEach(num, (Integer i) -> System.out.println(i));
    }
    @FunctionalInterface
    public interface Consumer<T> {
        void accept(T t);
    }
    public static <T> void forEach(List<T> list, Consumer<T> c) {
        list.stream().forEach(l -> {
            c.accept(l);
        });
    }

    /**
     * 函数式接口的使用——Function
     */
    private static void test5() {
        List<Integer> num = Arrays.asList(1, 2, 3, 4, 5);
        List<String> map = map(num, (Integer i) -> i.toString());
        System.out.println(map.get(0).getClass());
    }
    @FunctionalInterface
    public interface Function<T, R> {
        R apply(T t);
    }
    public static <T, R> List<R> map(List<T> list, Function<T, R> f) {
        List<R> result = new ArrayList<>();
        list.stream().forEach(l -> {
            result.add(f.apply(l));
        });
        return result;
    }

    /**
     * 函数式接口的使用——IntPredicate
     */
    public static void test6() {
        IntPredicate evenNumbers = (int i) -> i % 2 == 0;
        boolean test = evenNumbers.test(1000);
        System.out.println(test);
        Predicate<Integer> evenNumberss = (Integer i) -> i % 2 == 0;
        boolean test1 = evenNumberss.test(1000);
        System.out.println(test1);
    }
    @FunctionalInterface
    public interface IntPredicate {
        boolean test(int t);
    }

    /**
     * 自定义函数时接口
     */
    public static void test7() {
        String id = "110";
        int add = add(id, (String s) -> Objects.nonNull(s) ? 1 : 0);
        System.out.println(add);
    }
    @FunctionalInterface
    public interface selectService<T> {
        int query(String id);
    }
    public static int add(String id, selectService<String> service) {
        return service.query(id);
    }

    //-------------------------------------------------------------------------------------------
    /**
     * 方法引用
     */
    public static void test8() {
        List<Apple> list = new ArrayList<>();
        list.add(new Apple("臭狗砸", 222, "red"));
        list.add(new Apple("香仔仔", 111, "green"));

        list.sort((Apple a1, Apple a2) -> Integer.compare(a1.getWeight(), a2.getWeight()));
        System.out.println(list);

        list.sort(Comparator.comparing(Apple::getWeight).reversed());
        System.out.println(list);

    }



}
